﻿using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace Odyssey.Http.Implementations
{
    internal partial class HttpRequester
    {
        private string GenerateClientName(string client, HttpMethod httpMethod)
        {
            return $"{client}-{httpMethod.ToString().ToLower()}";
        }

        public virtual async Task<HttpResponseMessage> SendAsync(Uri uri, object data, HttpMethod httpMethod, string clientName = "", string contentType = "", IDictionary<string, string> requestHeaders = null, IHttpSerializer httpSerializer = null, Func<HttpResponseMessage, Task> responseMessagefilter = null)
        {
            httpSerializer = httpSerializer ?? _httpSerializer;
            return await SendAsync(uri, httpSerializer.Serialize(data), httpMethod, clientName, contentType, requestHeaders, responseMessagefilter);
        }

        public virtual async Task<HttpResponseMessage> SendAsync(Uri uri, string data, HttpMethod httpMethod, string clientName = "", string contentType = "", IDictionary<string, string> requestHeaders = null, Func<HttpResponseMessage, Task> responseMessagefilter = null)
        {
            var buffer = Encoding.UTF8.GetBytes(data);
            return await SendAsync(uri, buffer, httpMethod, clientName, contentType, requestHeaders, responseMessagefilter);
        }

        public virtual async Task<HttpResponseMessage> SendAsync(Uri uri, byte[] data, HttpMethod httpMethod, string clientName = "", string contentType = "", IDictionary<string, string> requestHeaders = null, Func<HttpResponseMessage, Task> responseMessagefilter = null)
        {
            if (_logger.IsEnabled(LogLevel.Information))
            {
                _logger.LogInformation($"post uri=[{uri.ToString()}] requestdata[{data}]");
            }
            if (string.IsNullOrWhiteSpace(clientName))
            {
                clientName = _httpConfiguration.DefaultClientName;
            }
            var client = _httpClientFactory.CreateClient(GenerateClientName(clientName, httpMethod));

            var requestMessage = new HttpRequestMessage(httpMethod, uri);
            if (requestHeaders != null)
            {
                foreach (var item in requestHeaders)
                {
                    requestMessage.Headers.Add(item.Key, item.Value);
                }
            }

            if (data != null && data.Length > 0)
            {
                var content = new ByteArrayContent(data);
                if (string.IsNullOrWhiteSpace(contentType))
                {
                    contentType = ContentType.Json;
                }
                content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
                //content.Headers.Add("charset", "utf-8");
                requestMessage.Content = content;
            }

            var responseMessage = await client.SendAsync(requestMessage);
            if (responseMessagefilter != null)
            {
                await responseMessagefilter.Invoke(responseMessage);
            }
            else
            {
                await _httpConfiguration.HttpResponseFilter?.Invoke(responseMessage);
            }
            return responseMessage;
        }
    }
}
